package com.qs.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qs.constant.OrderConstant;
import com.qs.constant.PayTypeConstant;
import com.qs.constant.RedisConstant;
import com.qs.pojo.entity.PayInfo;
import com.qs.mapper.PayInfoMapper;
import com.qs.pojo.enums.PayStatus;
import com.qs.pojo.vo.GoodsStockLockVo;
import com.qs.pojo.vo.OrderExpireVo;
import com.qs.pojo.vo.PayInfoVo;
import com.qs.service.IAsyncService;
import com.qs.service.IPayInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单支付记录表 服务实现类
 * </p>
 *
 * @author author
 * @since 2023-12-08
 */
@Service
@RequiredArgsConstructor
public class PayInfoServiceImpl extends ServiceImpl<PayInfoMapper, PayInfo> implements IPayInfoService {

    private final RedisTemplate redisTemplate;

    private final IAsyncService asyncService;

    @Override
    public List<OrderExpireVo> getWaitPayOrder(Integer userId) {
        if(null != userId){
            QueryWrapper<PayInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id",userId);
            queryWrapper.eq("status", PayStatus.WAIT_PAY);
            queryWrapper.orderByDesc("update_time");
            List<PayInfo> payInfos = baseMapper.selectList(queryWrapper);
            if(!CollectionUtils.isEmpty(payInfos)){
                List<OrderExpireVo> list = new ArrayList<OrderExpireVo>(payInfos.size());
                payInfos.stream().forEach(item -> {
                    String orderId = (String) redisTemplate.opsForValue().get(RedisConstant.ORDER_ID + item.getOrderId());
                    //超时订单不再返回
                    if(!StringUtils.isBlank(orderId)){
                        OrderExpireVo orderExpireVo = new OrderExpireVo();
                        orderExpireVo.setOrderId(item.getOrderId());
                        orderExpireVo.setTimestamp(redisTemplate.getExpire(RedisConstant.ORDER_ID + item.getOrderId(), TimeUnit.SECONDS));
                        list.add(orderExpireVo);
                    }else{
                        //将锁住的商品库存释放(对于超时订单而言)
                        List<GoodsStockLockVo> stockLockVoList = (List<GoodsStockLockVo>) redisTemplate.opsForValue().get(RedisConstant.GOODS_STOCK_LOCK + item.getOrderId());
                        if(!CollectionUtils.isEmpty(stockLockVoList)){
                            List<Integer> goodsId = stockLockVoList.stream().map(GoodsStockLockVo::getGoodsId).collect(Collectors.toList());
                            asyncService.deductionLockStock(goodsId,item.getOrderId());
                            //异步将order_cart的记录删除
                            asyncService.deleteOrderCart(item.getOrderId(),userId);
                            //根据orderId将超时订单记录qs_pay_info数据删除
                            asyncService.deleteOrderIdExpire(item.getOrderId());
                        }
                    }
                });
                if(!CollectionUtils.isEmpty(list)){
                    return list;
                }
                return null;
            }
            return null;
        }
        return null;
    }

    @Override
    public List<String> getHavePayOrderData(Integer userId) {
        if(null != userId){
            QueryWrapper<PayInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id",userId);
            queryWrapper.eq("status", PayStatus.HAVE_PAY);
            queryWrapper.orderByDesc("update_time");
            List<PayInfo> payInfos = baseMapper.selectList(queryWrapper);
            if(!CollectionUtils.isEmpty(payInfos)){
                List<String> orderIds = new ArrayList<String>(payInfos.size());
                payInfos.stream().forEach(item -> {
                    orderIds.add(item.getOrderId());
                });
                return orderIds;
            }
            return null;
        }
        return null;
    }

    @Override
    public Map<String,Object> getOrderCreateTime(String orderId) {
        QueryWrapper<PayInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", orderId);
        PayInfo payInfo = baseMapper.selectOne(wrapper);
        if (payInfo != null) {
            String redisOrderId = (String) redisTemplate.opsForValue().get(RedisConstant.ORDER_ID + orderId);
            //超时订单不再返回
            String createTime = LocalDateTimeUtil.format(LocalDateTimeUtil.parse(payInfo.getCreateTime().toString()), DatePattern.NORM_DATETIME_MINUTE_PATTERN);
            String payTime = LocalDateTimeUtil.format(LocalDateTimeUtil.parse(payInfo.getUpdateTime().toString()), DatePattern.NORM_DATETIME_MINUTE_PATTERN);
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("createTime", createTime);
            map.put("payTime", payTime);
            if(!StringUtils.isBlank(redisOrderId)){
                Long timestamp = redisTemplate.getExpire(RedisConstant.ORDER_ID + orderId, TimeUnit.SECONDS);
                map.put("timestamp", timestamp);
            }else{
                map.put("timestamp", null);
                //将锁住的商品库存释放(对于过期订单而言)
                List<GoodsStockLockVo> stockLockVoList = (List<GoodsStockLockVo>) redisTemplate.opsForValue().get(RedisConstant.GOODS_STOCK_LOCK + orderId);
                if(!CollectionUtils.isEmpty(stockLockVoList)){
                    List<Integer> goodsId = stockLockVoList.stream().map(GoodsStockLockVo::getGoodsId).collect(Collectors.toList());
                    asyncService.deductionLockStock(goodsId,orderId);
                    //异步将order_cart的记录删除
                    asyncService.deleteOrderCart(orderId,payInfo.getUserId());
                    //根据orderId将超时订单记录qs_pay_info数据删除
                    asyncService.deleteOrderIdExpire(orderId);
                }
            }
            return map;
        }
        return null;
    }

    @Override
    public List<Float> findWeekdayData() {
        List<PayInfoVo> weekdayData = baseMapper.findWeekdayData();
        List<Float> list = new ArrayList<>(Arrays.asList(0.0f, 0.0f, 0.0f, 0.0f,0.0f, 0.0f, 0.0f));
        if(!CollectionUtils.isEmpty(weekdayData)){
            for (PayInfoVo vo : weekdayData) {
                switch (vo.getDay()) {
                    case 1:
                        //星期天
                        list.add(6,vo.getPrice());
                        break;
                    case 2:
                        //星期一
                        list.add(0,vo.getPrice());
                        break;
                    case 3:
                        //星期二
                        list.add(1,vo.getPrice());
                        break;
                    case 4:
                        //星期三
                        list.add(2,vo.getPrice());
                        break;
                    case 5:
                        //星期四
                        list.add(3,vo.getPrice());
                        break;
                    case 6:
                        //星期五
                        list.add(4,vo.getPrice());
                        break;
                    case 7:
                        //星期六
                        list.add(5,vo.getPrice());
                        break;
                    default:
                        break;
                }
            }
        }
        return list;

    }

    @Override
    public Map<String, Object> findTotalOrderData() {
        QueryWrapper<PayInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("status",PayStatus.HAVE_PAY);
        List<PayInfo> payInfos = baseMapper.selectList(wrapper);
        //过滤出支付宝支付的订单
        List<PayInfo> aliPayOrders = payInfos.stream().filter(item -> item.getType().equalsIgnoreCase(PayTypeConstant.ALI_PAY)).collect(Collectors.toList());
        //过滤出微信支付的订单
        List<PayInfo> wechatOrders = payInfos.stream().filter(item -> item.getType().equalsIgnoreCase(PayTypeConstant.WX_PAY)).collect(Collectors.toList());
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("total",payInfos.size());
        map.put("alipay",aliPayOrders.size());
        map.put("wechat",wechatOrders.size());
        return map;
    }

    @Override
    public float findWeekTotalOrderData() {
        //查询出本周总流水
        return baseMapper.findWeekTotal();
    }

    @Override
    public float findThisYearData() {
        //查询出今年总流水
        return baseMapper.findThisYearData();
    }
}
